Check_AP Script - dynamic handling of multiple APs

Applicable Scenarios

It is not uncommon for a HamWAN client to be in a location where they can potentially connect to multiple HamWAN sectors (APs). In this situation, its likely that one of the APs will have a noticably better signal. Normally the client selects the best AP based on signal strength and any administrate restrictions (e.g. a connect list). However, if that selected sector drops offline for whatever reason, the client starts searching for a working AP, and connects. So far, working as intended. The client may not be on a optimal sector, but at least they are still connected to the network. The problem is that the client will never try to reconnect to the original (preferred) sector unless the current connection fails.

This is particularly problematic if the users of the client are trying to access the client or systems behind it such as Allstar nodes, routers, etc. Also the connection quality and bandwidth may make operation less that ideal.

This problem can be fixed by causing the client to go through is reconnection process through one of several methods:

Possible Options

Pin the client to one AP

There are a couple of options. You can restrict connections to a particular device (or devices). This can be done by setting a connect list:

/interface wireless connect interface=wlan1 mac-address=<mac-address-of-sector>

More information on this can be found in the RouterOS Documenation.

Another option is to set up a scanlist with only the sector entries you desire to use. This only works if you only see one site, but multiple sectors at that site. Here is an example

/interface wireless
set [ find default-name=wlan1 ] band=5ghz-onlyn channel-width=10mhz country=no_country_set disabled=no frequency-mode=superchannel radio-name=W7ACS-NSCEB \
   scan-list=HamWAN-S2 ssid=HamWAN wireless-protocol=nv2
/interface wireless channels
add band=5ghz-onlyn comment="Cell sites radiate this at 0 degrees (north)" frequency=5920 list=HamWAN name=Sector1-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 120 degrees (south-east)" frequency=5900 list=HamWAN name=Sector2-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 240 degrees (south-west)" frequency=5880 list=HamWAN name=Sector3-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 0 degrees (north)" frequency=5920 list=HamWAN name=Sector1-10 width=10
add band=5ghz-onlyn comment="Cell sites radiate this at 120 degrees (south-east)" frequency=5900 list=HamWAN name=Sector2-10 width=10
add band=5ghz-onlyn comment="Cell sites radiate this at 240 degrees (south-west)" frequency=5880 list=HamWAN name=Sector3-10 width=10
add band=5ghz-onlyn comment="Cell sites radiate this at 0 degrees (north)" frequency=5920 list=HamWAN-S1 name=Sector1-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 0 degrees (north)" frequency=5920 list=HamWAN-S1 name=Sector1-10 width=10
add band=5ghz-onlyn comment="Cell sites radiate this at 120 degrees (south-east)" frequency=5900 list=HamWAN-S2 name=Sector2-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 120 degrees (south-east)" frequency=5900 list=HamWAN-S2 name=Sector2-10 width=10
add band=5ghz-onlyn comment="Cell sites radiate this at 240 degrees (south-west)" frequency=5880 list=HamWAN-S3 name=Sector3-5 width=5
add band=5ghz-onlyn comment="Cell sites radiate this at 240 degrees (south-west)" frequency=5880 list=HamWAN-S3 name=Sector3-10 width=10

In this example, I have created limited scan lists for each sector and the radio is using one of these (scan-list=HamWAN-S2). If you use this option you can omit or delete any lists you are not using, but I recommend keeping at least the full list (HamWAN) in case you need it later.

Make multiple options viable

This can be done by configuring routing on multiple sectors and then accessing resources at the client using local LAN addresses that are assigned from the HamWAN address space and supported by dynamic OSPF routing on the sectors. The downside is that you may still be connected to a non-optimal sector with lower bandwidth or potential weak signal induced flakiness.

Periodically check for optimal AP connection

This choice preserves the option to connect to other APs but periodically checks to see if my preferred sector is available and forces a reconnection. The Check_AP script realizes this functionality. This client impact is a small glitch in connectivity nominally once an hour when it rescans for the desired AP, but otherwise no impact on connectivity.

Check_AP Script

This is the script with appropriate escaping so the it looks readable when viewed on RouterOS, while also maintaining its readability on a source host.

To install this on a client, follow these steps:

  1. Determine what is the radio-name of sector you wish to be primary, for example “S2.Beacon/K7WAN”. You can determine the radio-name by logging into the client terminal interface and issuing this command:

    /interface wireless monitor 0
  2. Download a copy of the Check_AP script such as the one below.

  3. Rename the script to Check_AP_-.rsc or simply Check_AP.rsc.

  4. Modify the file with your primary AP radio-name. Around line 17 you will Find the line that begins “:local primaryRadioName”. Change the name to your desired AP (sector) radio name, for example “S2.Beacon/K7WAN”. These are only loose standardized so you will see some variation.

  5. Upload the file to your client using scp or WinBox.

  6. Import the script using whatever name you assigned and uploaded:

    /import file=Check_AP.rsc verbose=yes

    verbose=yes lets you see where if fails if there is an error on the import.

  7. Test the script and deal with any errors you encounter before adding a scheduler entry.

    /system script run Check_AP
  8. Add a scheduler entry to check your AP periodically and attempt to connect to your primary if you have wound up on a less desirable one. The needed command is in the script header comments.

    /system scheduler add name="Check_AP_hourly" interval=1h on-event="Check_AP"

Here is the full script with escaping to allow cut/paste or importing. The basic process is:

  1. run a wireless monitor command and extract the current status
  2. if connected, check if the radio-name is our desired AP radio-name
  3. if not, do one pass of interface scan which has a side effect of disconnecting and then initiating the connect process when the scan completes.
  4. if it is connect properly or not connected at all, it just prints a log message. If its not connected, its already trying to find any working connection.
/system script add name="Check_AP" source="{\
\n    # =================================================================\
\n    # Script: WiFi AP Connection Check\
\n    # RouterOS Version: 7.x\
\n    #\
\n    # Description: Checks if a WiFi station interface is connected to\
\n    # its designated primary Access Point. If it's connected to any\
\n    # other AP, it forces a rescan to encourage it to find the\
\n    # primary AP again.\
\n    #\
\n    # Set to run hourly with this command:\
\n    # /system scheduler add name=\"Check_AP_hourly\" interval=1h on-event=\"Check_AP\"\
\n    # =================================================================\
\n\
\n    # --- Script Configuration ---\
\n    # Set the radio-name of your PREFERRED/PRIMARY access point.\
\n    :local primaryRadioName \"Mapleleaf-S3/K7WAN\"\
\n    # Set the name of your WiFi station (client) interface (normally \"wlan1\").\
\n    :local wifiInterface \"wlan1\"\
\n    # --- End of Configuration ---\
\n\
\n    # Do not edit below this line unless you know what you are doing.\
\n\
\n    /log info message=\"AP Check: Starting check for interface '\$wifiInterface'.\"\
\n\
\n    # This direct method is more robust. It queries the status and radio-name\
\n    # separately to avoid issues with variable types from the monitor command.\
\n    :local monitorResult [/interface wireless monitor [find name=wlan1] once as-value]\
\n    :local currentStatus (\$monitorResult->\"status\")\
\n    :local currentRadioName (\$monitorResult->\"radio-name\")\
\n\
\n    # Check if the interface is actually connected to any access point\
\n    if (\$currentStatus = \"connected-to-ess\") do={\
\n        # Now, check if the connected AP is NOT the primary one\
\n        if (\$currentRadioName != \$primaryRadioName) do={\
\n            /log warning message=\"AP Check: '\$wifiInterface' is connected to non-primary AP (\$currentRadioName). Forcing rescan to find \$primaryRadioName.\"\
\n\
\n            # Force the interface to scan for other networks\
\n            /interface wireless scan \$wifiInterface rounds=1\
\n            :delay 5s\
\n            /ip dhcp-client renew \$wifiInterface\
\n        } else={\
\n            /log info message=\"AP Check: '\$wifiInterface' is correctly connected to primary AP (\$currentRadioName).\"\
\n        }\
\n    } else={\
\n        /log info message=\"AP Check: '\$wifiInterface' is not connected (Current Status: \$currentStatus).\"\
\n    }\
\n}" policy=read,write

Attachments

Filename Size Modified
Check_AP_Mapleleaf-S3.rsc 2.5KiB 2025-10-25 10:11:33